from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from fastapi.middleware.cors import CORSMiddleware
from fastapi.exceptions import RequestValidationError
from starlette.exceptions import HTTPException as StarletteHTTPException
import os
import logging
import traceback
from app.api import api_router
from app.core.config import settings

app = FastAPI(
    title=settings.PROJECT_NAME,
    version=settings.PROJECT_VERSION
)

# 设置日志
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s",
    handlers=[
        logging.StreamHandler()
    ]
)

# 配置CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 确保目录存在
os.makedirs(settings.UPLOADS_DIR, exist_ok=True)
os.makedirs(settings.PRODUCTS_DIR, exist_ok=True)

# 获取当前文件的绝对路径
current_file = os.path.abspath(__file__)
# 获取app目录的绝对路径
app_dir = os.path.dirname(current_file)
# 获取模板目录的绝对路径
templates_dir = os.path.join(app_dir, "templates")

# 配置模板
templates = Jinja2Templates(directory=templates_dir)
logging.info(f"模板目录路径: {templates_dir}")

# 挂载静态文件目录
app.mount("/static", StaticFiles(directory=settings.STATIC_DIR), name="static")
logging.info(f"静态文件目录: {settings.STATIC_DIR}")
logging.info(f"上传目录: {settings.UPLOADS_DIR}")
logging.info(f"产品目录: {settings.PRODUCTS_DIR}")

# 添加全局异常处理
@app.exception_handler(StarletteHTTPException)
async def http_exception_handler(request: Request, exc: StarletteHTTPException):
    logging.error(f"HTTP异常: {exc.detail}")
    return JSONResponse(
        status_code=exc.status_code,
        content={"message": exc.detail}
    )

@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
    logging.error(f"请求验证异常: {str(exc)}")
    return JSONResponse(
        status_code=422,
        content={"message": "请求参数验证失败", "details": str(exc)}
    )

@app.exception_handler(Exception)
async def general_exception_handler(request: Request, exc: Exception):
    logging.error(f"未处理异常: {str(exc)}")
    logging.error(traceback.format_exc())
    return JSONResponse(
        status_code=500,
        content={"message": "服务器内部错误", "details": str(exc)}
    )

# 注册路由
app.include_router(api_router, prefix=settings.API_PREFIX)

@app.get("/", response_class=HTMLResponse)
async def index(request: Request):
    """首页"""
    try:
        return templates.TemplateResponse("index.html", {
            "request": request,
            "default_product_image": settings.DEFAULT_PRODUCT_IMAGE,
            "fallback_image_url": settings.FALLBACK_IMAGE_URL
        })
    except Exception as e:
        logging.error(f"渲染首页模板失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"渲染模板失败: {str(e)}")

@app.get("/products", response_class=HTMLResponse)
async def products_page(request: Request):
    """产品列表页"""
    try:
        return templates.TemplateResponse("products.html", {
            "request": request,
            "default_product_image": settings.DEFAULT_PRODUCT_IMAGE,
            "fallback_image_url": settings.FALLBACK_IMAGE_URL
        })
    except Exception as e:
        logging.error(f"渲染产品列表模板失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"渲染模板失败: {str(e)}")

@app.get("/products/{product_id}", response_class=HTMLResponse)
async def product_detail(request: Request, product_id: str):
    """产品详情页"""
    try:
        return templates.TemplateResponse("product_detail.html", {
            "request": request, 
            "product_id": product_id,
            "default_product_image": settings.DEFAULT_PRODUCT_IMAGE,
            "fallback_image_url": settings.FALLBACK_IMAGE_URL
        })
    except Exception as e:
        logging.error(f"渲染产品详情模板失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"渲染模板失败: {str(e)}")

@app.get("/create-product", response_class=HTMLResponse)
async def create_product_page(request: Request):
    """创建产品页面"""
    try:
        return templates.TemplateResponse("create_product.html", {
            "request": request,
            "default_product_image": settings.DEFAULT_PRODUCT_IMAGE,
            "fallback_image_url": settings.FALLBACK_IMAGE_URL
        })
    except Exception as e:
        logging.error(f"渲染创建产品模板失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"渲染模板失败: {str(e)}")

@app.get("/compare-products", response_class=HTMLResponse)
async def compare_products(request: Request):
    """产品对比页"""
    try:
        return templates.TemplateResponse("compare_products.html", {
            "request": request,
            "default_product_image": settings.DEFAULT_PRODUCT_IMAGE,
            "fallback_image_url": settings.FALLBACK_IMAGE_URL
        })
    except Exception as e:
        logging.error(f"渲染产品对比模板失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"渲染模板失败: {str(e)}")

@app.get("/chat", response_class=HTMLResponse)
async def chat_page(request: Request):
    """AI聊天页面"""
    try:
        import datetime
        current_time = datetime.datetime.now().strftime("%H:%M")
        return templates.TemplateResponse("chat.html", {
            "request": request, 
            "current_time": current_time,
            "default_product_image": settings.DEFAULT_PRODUCT_IMAGE,
            "fallback_image_url": settings.FALLBACK_IMAGE_URL
        })
    except Exception as e:
        logging.error(f"渲染聊天模板失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"渲染模板失败: {str(e)}")

@app.get("/wordcloud", response_class=HTMLResponse)
async def wordcloud_page(request: Request):
    """词云分析页面"""
    try:
        return templates.TemplateResponse("wordcloud.html", {
            "request": request,
            "default_product_image": settings.DEFAULT_PRODUCT_IMAGE,
            "fallback_image_url": settings.FALLBACK_IMAGE_URL
        })
    except Exception as e:
        logging.error(f"渲染词云模板失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"渲染模板失败: {str(e)}")

# 启动服务器
if __name__ == "__main__":
    import uvicorn
    uvicorn.run("app.main:app", host="127.0.0.1", port=8001, reload=True)